package com.example.mansystem.exception;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.mansystem.Annotation.DataBindErrorTips;
import com.example.mansystem.entity.CallResultMsg;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.lang.reflect.Field;
import java.util.List;

@RestControllerAdvice(annotations = RestController.class)
public class UniformReponseHandler<T> {

    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg sendSuccessResponse(){
        return new CallResultMsg( CodeAndMsg.SUCCESS, null);
    }

    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg sendSuccessResponse(T data) {
        return new CallResultMsg( CodeAndMsg.SUCCESS, data);
    }

    @ExceptionHandler(UserDefinedException.class)
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg sendErrorResponse_UserDefined(Exception exception){
        return new CallResultMsg( ((UserDefinedException)exception).getException(), null);
    }

    @ExceptionHandler({MethodArgumentTypeMismatchException.class})
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg DtoValidatedError(MethodArgumentTypeMismatchException exception)
    {
        String data = exception.getMessage();
        return new CallResultMsg(CodeAndMsg.Dto_Invalidate,data);
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg DtoMismatchError(MethodArgumentNotValidException exception)
    {
        String data = exception.getMessage();
        return new CallResultMsg(CodeAndMsg.Dto_Invalidate,data);
    }


    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseStatus(HttpStatus.OK)
    public CallResultMsg HttpMessageNotReadableError(HttpMessageNotReadableException e)
    {
        String erroMessage = e.getMessage();
//        Throwable rootCause = e.getRootCause();
//        if (rootCause instanceof JsonMappingException) {
//            erroMessage = getDataBindErrorTips(((JsonMappingException) rootCause).getPath());
//        }
//        if (erroMessage == null) {
//            erroMessage = "参数解析失败";
//        }

        return new CallResultMsg(CodeAndMsg.BatchRegisterErr,erroMessage);
    }

//    private String getDataBindErrorTips(List<JsonMappingException.Reference> path) {
//        if (CollectionUtils.isEmpty(path)) {
//            return null;
//        }
//        for (int i = path.size() - 1; i >= 0; i--) {//基本只需要最后一条数据
//            JsonMappingException.Reference reference = path.get(i);
//            if (reference == null) {
//                continue;
//            }
//            Object target = reference.getFrom();
//            if (target == null) {
//                continue;
//            }
//            Class<?> targetCalss = target.getClass();
//            String result = this.getDataBindErrorTips(target.getClass(), reference.getFieldName());
//            if (!StringUtils.isEmpty(result)) {
//                return result;
//            }
//        }
//        return null;
//    }
//    private String getDataBindErrorTips(Class<?> targetCalss, String fieldName) {
//        if (targetCalss == null || StringUtils.isEmpty(fieldName)) {
//            return null;
//        }
//        while (targetCalss != Object.class) {
//            Field field;
//            try {
//                field = targetCalss.getDeclaredField(fieldName);
//                DataBindErrorTips dataBindErrorTips = field.getDeclaredAnnotation(DataBindErrorTips.class);
//                return dataBindErrorTips == null ? null : dataBindErrorTips.value();
//            } catch (NoSuchFieldException e) {
//                targetCalss = targetCalss.getSuperclass();
//            }
//        }
//        return null;
//    }

//    @ExceptionHandler(Exception.class)
//    @ResponseStatus(HttpStatus.OK)
//    public CallResultMsg sendErrorResponse_System(Exception exception){
//        if (exception instanceof UserDefinedException) {
//            return this.sendErrorResponse_UserDefined(exception);
//        }
//
//        return new CallResultMsg( CodeAndMsg.UNKNOWEXCEPTION, null);
//    }
}
